package com.wf.atm.server;
import com.wf.atm.service.Bank;
import com.wf.atm.utils.ThreadPoolUtils;
import com.wf.atm.config.ThreadPoolConfig;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.LockSupport;

/**
 * @Description 服务器主界面
 * @Author fqq
 * @Date 2023/8/30 16:08
 */
public class ServerPanel extends JPanel {
    //通信资源
    ServerSocket serverSocket;
    //存储所有客户端的socket的容器
    CopyOnWriteArrayList<Socket> list;
    //bank实例
    Bank bank;
    //标识 控制是否等待接入客户端
   // ThreadPoolUtils pool;
    boolean accept = false;
    public ServerPanel() {
        this.list = new CopyOnWriteArrayList<>();
        this.bank = Bank.getInstance();
       // this.pool= new ThreadPoolUtils(ThreadPoolConfig.CORE_POOL_SIZE, ThreadPoolConfig.MAX_POOL_SIZE, ThreadPoolConfig.QUEUE_SIZE);

        initComponents();
    }

    //启动服务器
    private void startButtonActionPerformed(ActionEvent e) {
        //计数器+1 只要计数器加至1，则开始执行任务
        CyclicBarrier barrier = new CyclicBarrier(1, this::startWork);

        //单独启动线程池中的线程 来执行任务
        ThreadPoolUtils.execute(()->{
            try {
                //启动服务器
                serverSocket = new ServerSocket(8090);
                //允许接入客户端
                accept = true;
                //改变启动按钮为禁用
                startButton.setEnabled(false);
                //改变关闭按钮为可用
                closeButton.setEnabled(true);
                //计数器+1
                barrier.await();
            } catch (IOException | BrokenBarrierException | InterruptedException ex) {
                System.out.println(ex.getMessage());
            }
        });
    }

    //启动服务器后做的任务：等等接入客户端
    private void startWork(){
        try {
            while(accept){
                //等待接入客户端
                Socket socket = serverSocket.accept();
                System.out.println(socket.getRemoteSocketAddress()+"客户端接入成功");

                //将客户端的socket添加到list集合中
                list.add(socket);
                //让线程池中的线程执行任务：分配serverTasker工作
                ServerTasker tasker = new ServerTasker(socket,bank,Thread.currentThread(),list);

                ThreadPoolUtils.execute(tasker);

                //如果线程池中的能执行的任务数量已达上限 阻塞当前线程 ：停止接入客户端
                if(list.size() == ThreadPoolConfig.MAX_CLIENTS){
                    //停止接入客户端 暂时关闭服务器
                    serverSocket.close();
                    serverSocket = null;
                    //线程通讯： 阻塞当前线程
                    LockSupport.park();
                    System.out.println("---blocking-");
                    //延迟：确保线程有 时间归还到线程池中
                    Thread.sleep(500);
                    //再次开启服务器
                    serverSocket = new ServerSocket(8090);
                }
            }
        }catch (SocketException e){//socket closed
            JOptionPane.showMessageDialog(null,"服务器已关闭~~~");
        }catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }


    //关闭服务器
    private void closeButtonActionPerformed(ActionEvent e)  {
        if(serverSocket==null){
            JOptionPane.showMessageDialog(null,"服务器还没开启");
            return;
        }
        //服务器开启中 且未被关闭：
        if(!serverSocket.isClosed()){
            //遍历list 逐一关闭所有客户端的套接字 并且清空集合
            list.forEach(socket -> {
                if(socket!=null){
                    try {
                        socket.close();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            });
            //清空集合
            list.clear();
            //不允许接入客户端
            accept = false;
            //改变启动按钮为 可用
            startButton.setEnabled(true);
            //改变关闭按钮为 禁用
            closeButton.setEnabled(false);

            try {
                //关闭服务器
                serverSocket.close();
                serverSocket = null;//保证下一次开启服务器是正常的
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }else{
            JOptionPane.showMessageDialog(null,"服务器已被关闭");
        }
    }

    //查询银行信息
    private void queryButtonActionPerformed(ActionEvent e) {
        //跳转至RankPanel
        CardLayout card = (CardLayout)this.getParent().getLayout();
        card.show(getParent(),"rank");
    }

    private void initComponents() {
        // JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
        label = new JLabel();
        startButton = new JButton();
        closeButton = new JButton();
        queryButton = new JButton();

        //======== this ========
        setLayout(null);

        //---- label ----
        label.setText("服  务  器");
        label.setFont(new Font("Microsoft YaHei UI", Font.BOLD, 20));
        label.setHorizontalAlignment(SwingConstants.CENTER);
        add(label);
        label.setBounds(120, 145, 200, 40);

        //---- startButton ----
        startButton.setText("启动服务器");
        startButton.addActionListener(e -> startButtonActionPerformed(e));
        add(startButton);
        startButton.setBounds(50, 260, 110, 35);

        //---- closeButton ----
        closeButton.setText("关闭服务器");
        closeButton.addActionListener(e -> closeButtonActionPerformed(e));
        add(closeButton);
        closeButton.setBounds(280, 260, 110, 35);

        //---- queryButton ----
        queryButton.setText("上帝视角");
        queryButton.addActionListener(e -> queryButtonActionPerformed(e));
        add(queryButton);
        queryButton.setBounds(350, 70, 93, 35);

        setPreferredSize(new Dimension(395, 400));
        // JFormDesigner - End of component initialization  //GEN-END:initComponents
    }

    // JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
    private JLabel label;
    private JButton startButton;
    private JButton closeButton;
    private JButton queryButton;
    // JFormDesigner - End of variables declaration  //GEN-END:variables
}

